{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 使用 qianfan sdk 构建本地评估模型\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "千帆大模型平台提供了在线进行自动评估的方式，而有时我们希望有更灵活的自动评估方式。\n",
    "\n",
    "本文将以评估文本摘要效果为例子来介绍\n",
    "\n",
    "1. 如何使用千帆 sdk 封装自定义本地评估方法\n",
    "2. 使用函数封装手搓其原理实现。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "以下是本文封装部分使用的库与作用\n",
    "    Dataset：提供数据集接口，用于构造待评估数据集，方便在本地、平台、huggingface多端拉取数据集。\n",
    "    Prompt：提供数据模板，用于指导模型进行评估，可联网获取prompt或者使用prompt优化功能。\n",
    "    Service：提供模型服务接口，在evaluateManager中为没有生成答案的数据集提供生成能力。\n",
    "    EvaluateManager：提供评估任务管理功能，封装了异步调用算子，可以方便地实现多线程评估。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此处使用0.3.0版本以上的qianfan sdk。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "! pip install -U \"qianfan>=0.3.0\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "进行鉴权认证。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:25.247693Z",
     "start_time": "2024-02-01T06:10:25.233553Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ['QIANFAN_ACCESS_KEY'] = 'your_access_key'\n",
    "os.environ['QIANFAN_SECRET_KEY'] = 'your_secret_key'\n",
    "\n",
    "# 使用 Service 对象进行评估时，请按实际情况填写 QPS LIMIT，\n",
    "# 取值为所有 Service QPS Limit中的最小值\n",
    "os.environ[\"QIANFAN_QPS_LIMIT\"] = \"1\"\n",
    "os.environ['QIANFAN_LLM_API_RETRY_COUNT'] = \"3\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据与模板准备\n",
    "\n",
    "首先构造待评估数据集，此处用本地数据集，也可以拉取千帆平台上的数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:27.411148Z",
     "start_time": "2024-02-01T06:10:27.378756Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] [03-19 18:45:32] dataset.py:489 [t:139823724164928]: no data source was provided, construct\n",
      "[INFO] [03-19 18:45:32] dataset.py:358 [t:139823724164928]: construct a file data source from path: data_summerize/excerpt.jsonl, with args: {'input_columns': ['prompt'], 'reference_column': 'response'}\n",
      "[INFO] [03-19 18:45:32] file.py:165 [t:139823724164928]: use format type FormatType.Jsonl\n",
      "[INFO] [03-19 18:45:32] dataset.py:934 [t:139823724164928]: list local dataset data by 0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'prompt': '新华社受权于18日全文播发修改后的《中华人民共和国立法法》，修改后的立法法分为“总则”“法律”“行政法规”“地方性法规、自治条例和单行条例、规章”“适用与备案审查”“附则”等6章，共计105条。', 'response': [['修改后的立法法全文公布']]}]\n"
     ]
    }
   ],
   "source": [
    "from qianfan.dataset import Dataset\n",
    "\n",
    "ds = Dataset.load(data_file=\"data_summerize/excerpt.jsonl\", organize_data_as_group=False, input_columns=[\"prompt\"], reference_column=\"response\")\n",
    "\n",
    "print(ds[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后创建prompt模版，用于引导模型进行评估。\n",
    "\n",
    "由于摘要任务没有标准答案，所以此处模板不提供，如果是评估问答任务，则需要提供标准答案以评估正确率。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着指定评估指标和评估步骤。\n",
    "\n",
    "此处从四个维度进行评估，分别是相关性、连贯性、一致性、流畅度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:22:08.701604Z",
     "start_time": "2024-02-01T06:22:08.693796Z"
    }
   },
   "outputs": [],
   "source": [
    "from qianfan.common import Prompt\n",
    "\n",
    "evaluation_prompt_template = \"\"\"\n",
    "你是一名裁判员，负责为给定新闻的摘要评分。\n",
    "\n",
    "评价标准：\n",
    "\n",
    "{criteria}\n",
    "\n",
    "请你遵照以下的评分步骤：\n",
    "{steps}\n",
    "\n",
    "\n",
    "例子：\n",
    "\n",
    "新闻：\n",
    "\n",
    "{prompt}\n",
    "\n",
    "摘要：\n",
    "\n",
    "{response}\n",
    "\n",
    "\n",
    "根据答案的综合水平给出0到{max_score}之间的整数评分。\n",
    "如果答案存在明显的不合理之处，则应给出一个较低的评分。\n",
    "如果答案符合以上要求并且与参考答案含义相似，则应给出一个较高的评分\n",
    "\n",
    "你的回答模版如下:\n",
    "评分: 此处只能回答整数评分\n",
    "原因: 此处只能回答评分原因\n",
    "\"\"\"\n",
    "\n",
    "evaluation_prompt = Prompt(evaluation_prompt_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "相关性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:32.270724Z",
     "start_time": "2024-02-01T06:10:32.263641Z"
    }
   },
   "outputs": [],
   "source": [
    "relevance_metric = \"\"\"\n",
    "相关性 - 摘要中重要内容的选择。 \\ \n",
    "摘要只应包含来自源文档的重要信息。 \\\n",
    "惩罚包含冗余和多余信息的摘要。\n",
    "\"\"\"\n",
    "\n",
    "relevance_steps = \"\"\"\n",
    "1. 仔细阅读摘要和源文档。\n",
    "2. 将摘要与源文档进行比较，并识别文章的主要观点。\n",
    "3. 评估摘要是否涵盖了文章的主要观点，以及它包含多少无关或冗余信息。\n",
    "\"\"\"\n",
    "\n",
    "relevance_max_score = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "连贯性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-02T01:51:58.906967Z",
     "start_time": "2024-02-02T01:51:58.901448Z"
    }
   },
   "outputs": [],
   "source": [
    "\n",
    "coherence_metric = \"\"\"\n",
    "连贯性 - 所有句子的总体质量。 \\\n",
    "我们将此维度与 DUC 质量问题结构性和连贯性相关， \\\n",
    "其中“摘要应具有良好的结构和组织，不应只是相关信息的堆叠，而应基于从句子到主题有关的信息的连贯性主体进行构建。” \\\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "coherence_steps = \"\"\"\n",
    "1. 仔细阅读文章并识别主要主题和关键点。\n",
    "2. 阅读摘要并与文章进行比较。检查摘要是否涵盖了文章的主要主题和关键点，并以清晰且逻辑的顺序呈现它们\n",
    "\"\"\"\n",
    "\n",
    "coherence_max_score = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一致性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:40.222390Z",
     "start_time": "2024-02-01T06:10:40.177616Z"
    }
   },
   "outputs": [],
   "source": [
    "consistency_metric = \"\"\"\n",
    "一致性 - 摘要与摘要源的客观对齐。 \\\n",
    "客观一致的摘要只包含与源文档支持的陈述。 \\\n",
    "惩罚包含幻觉事实的摘要。\n",
    "\"\"\"\n",
    "\n",
    "consistency_steps = \"\"\"\n",
    "1. 仔细阅读文章并识别主要事实和细节。\n",
    "2. 阅读摘要并与文章进行比较。检查摘要是否包含任何不支持的文章的事实错误。\n",
    "3. 基于评估标准，为一致性分配分数。\n",
    "\"\"\"\n",
    "\n",
    "consistency_max_score = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "流畅度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:40.222864Z",
     "start_time": "2024-02-01T06:10:40.181288Z"
    }
   },
   "outputs": [],
   "source": [
    "fluency_metric = \"\"\"\n",
    "流畅度：摘要的语法、拼写、标点、单词选择和句子结构的质量。\n",
    "1：差。摘要有很多错误，使它难以理解或听起来不自然。\n",
    "2：中。摘要有一些影响文本清晰度或流畅性的错误，但要点仍然可理解。\n",
    "3：好。摘要很少或没有错误，易于阅读和遵循。\n",
    "\"\"\"\n",
    "\n",
    "fluency_steps = \"\"\"\n",
    "读取摘要并基于给定的标准评估其流畅度。从 1 到 3 分配一个流畅度分数。\n",
    "\"\"\"\n",
    "\n",
    "fluency_max_score = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:10:40.322359Z",
     "start_time": "2024-02-01T06:10:40.228181Z"
    },
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "evaluation_metrics = {\n",
    "    \"Relevance\": (relevance_metric, relevance_steps, relevance_max_score),\n",
    "    \"Coherence\": (coherence_metric, coherence_steps, coherence_max_score),\n",
    "    \"Consistency\": (consistency_metric, consistency_steps, consistency_max_score),\n",
    "    \"Fluency\": (fluency_metric, fluency_steps, fluency_max_score),\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "通过千帆sdk，我们有两种方法实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 方法一：封装本地评估器\n",
    "\n",
    "使用千帆平台提供的本地评估工具类进行评估\n",
    "此方法封装了异步请求，可以根据数据量并发进行评估\n",
    "\n",
    "首先继承LocalEvaluator类，并实现evaluate方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:11:26.190584Z",
     "start_time": "2024-02-01T06:11:26.124390Z"
    },
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import json\n",
    "from typing import Any, Dict, List, Union, Optional\n",
    "\n",
    "from qianfan import ChatCompletion\n",
    "from qianfan.common import Prompt\n",
    "from qianfan.utils.pydantic import Field\n",
    "from qianfan.evaluation.evaluator import LocalEvaluator\n",
    "from qianfan.evaluation.consts import (\n",
    "    QianfanRefereeEvaluatorPromptTemplate,\n",
    "    QianfanRefereeEvaluatorDefaultMaxScore,\n",
    "    QianfanRefereeEvaluatorDefaultMetrics,\n",
    "    QianfanRefereeEvaluatorDefaultSteps,\n",
    ")\n",
    "\n",
    "\n",
    "class LocalJudgeEvaluator(LocalEvaluator):\n",
    "\n",
    "    model: Optional[ChatCompletion] = Field(default=None, description=\"model object\")\n",
    "    metric_name: str = Field(default=\"\", description=\"metric name for evaluation\")\n",
    "    evaluation_prompt: Prompt = Field(default=Prompt(QianfanRefereeEvaluatorPromptTemplate), description=\"concrete evaluation prompt string\")\n",
    "    prompt_metrics: str = Field(default=QianfanRefereeEvaluatorDefaultMetrics, description=\"evaluation metrics\")\n",
    "    prompt_steps: str = Field(default=QianfanRefereeEvaluatorDefaultSteps, description=\"evaluation steps\")\n",
    "    prompt_max_score: int = Field(default=QianfanRefereeEvaluatorDefaultMaxScore, description=\"max score for evaluation\")\n",
    "    \n",
    "    class Config:\n",
    "        arbitrary_types_allowed = True\n",
    "    def evaluate(\n",
    "        self, input: Union[str, List[Dict[str, Any]]], reference: str, output: str\n",
    "    ) -> Dict[str, Any]:\n",
    "        \"\"\"\n",
    "        使用模型进行本地评估\n",
    "        :param input: 给定的prompt，\n",
    "            evaluateManager.eval()的is_chat参数为true时,\n",
    "            input为对话记录，否则为单字符串prompt\n",
    "        :param reference: 用户给定的标准答案\n",
    "        :param output: 大模型生成的结果，eval中由service生成，eval_only中由用户给定\n",
    "\n",
    "        :return: 评估结果\n",
    "        \"\"\"\n",
    "        if isinstance(input, list):\n",
    "            if not isinstance(self.model, ChatCompletion):\n",
    "                raise ValueError(f\"model is not an instance of ChatCompletion\")\n",
    "            if len(input)!=1:  # 只考虑ChatCompletion单文本输入的情况\n",
    "                raise ValueError(f\"chat history is not single text\")\n",
    "            input_content = input[0].get('content','')\n",
    "            \n",
    "            # 生成评价模板\n",
    "            prompt_text, _ = self.evaluation_prompt.render(\n",
    "                metric_name=self.metric_name,\n",
    "                criteria=self.prompt_metrics,\n",
    "                steps=self.prompt_steps,\n",
    "                max_score=self.prompt_max_score,\n",
    "                prompt=input_content,\n",
    "                response=reference,\n",
    "            )\n",
    "            \n",
    "            # 调用模型获得评分\n",
    "            msg = qianfan.Messages()\n",
    "            msg.append(prompt_text)\n",
    "            \n",
    "            resp = self.model.do(\n",
    "                messages=msg,\n",
    "                temperature=0.1,\n",
    "                top_p=1,\n",
    "            )\n",
    "            \n",
    "            # print(f'{self.metric_name}|{input[0]}|{output}|{resp[\"result\"].strip()}')\n",
    "            return {self.metric_name: resp[\"result\"].strip()}\n",
    "        else:\n",
    "            raise ValueError(f\"input in {type(input)} not supported\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:11:26.227581Z",
     "start_time": "2024-02-01T06:11:26.195551Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[WARNING] [03-19 18:45:32] model.py:374 [t:139823724164928]: service type should be specified before exec\n"
     ]
    }
   ],
   "source": [
    "import qianfan\n",
    "from qianfan.model import Service\n",
    "\n",
    "eb_turbo_service = Service(model=\"ERNIE-Bot-turbo\")  # 加载生成回答的服务\n",
    "chat_comp = qianfan.ChatCompletion(model=\"ERNIE-Bot-4\")  # 实例化用于裁判的模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "附加本地评估器，供EvaluationManager调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:11:26.230613Z",
     "start_time": "2024-02-01T06:11:26.203171Z"
    },
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "local_evaluators = []\n",
    "for eval_type, (criteria, steps, max_score) in evaluation_metrics.items():\n",
    "    local_evaluator = LocalJudgeEvaluator(\n",
    "        evaluation_prompt=Prompt(evaluation_prompt_template),\n",
    "        prompt_metrics=criteria,\n",
    "        prompt_steps=steps,\n",
    "        prompt_max_score=max_score,\n",
    "        model=chat_comp,\n",
    "        metric_name=eval_type\n",
    "    )\n",
    "    local_evaluators.append(local_evaluator)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:12:22.750470Z",
     "start_time": "2024-02-01T06:11:26.208960Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] [03-19 18:45:32] evaluation_manager.py:420 [t:139823724164928]: start to inference in batch during evaluation\n",
      "[INFO] [03-19 18:45:32] dataset.py:934 [t:139821972965120]: list local dataset data by None\n",
      "[INFO] [03-19 18:45:32] openapi_requestor.py:244 [t:139821947754240]: requesting llm api endpoint: /chat/eb-instant\n",
      "[INFO] [03-19 18:45:32] openapi_requestor.py:244 [t:139821964572416]: requesting llm api endpoint: /chat/eb-instant\n",
      "[INFO] [03-19 18:45:32] oauth.py:207 [t:139821947754240]: trying to refresh access_token for ak `9FtfEV***`\n",
      "[INFO] [03-19 18:45:32] openapi_requestor.py:244 [t:139821956163328]: requesting llm api endpoint: /chat/eb-instant\n",
      "[INFO] [03-19 18:45:32] oauth.py:220 [t:139821947754240]: sucessfully refresh access_token\n",
      "[INFO] [03-19 18:45:36] base.py:89 [t:139821956163328]: All tasks finished, exeutor will be shutdown\n",
      "[INFO] [03-19 18:45:36] evaluation_manager.py:444 [t:139823724164928]: start to evaluate llm 0\n",
      "[INFO] [03-19 18:45:36] openapi_requestor.py:244 [t:139821964572416]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:36] openapi_requestor.py:244 [t:139821956163328]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:36] openapi_requestor.py:244 [t:139821947754240]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:43] openapi_requestor.py:244 [t:139821947754240]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:44] openapi_requestor.py:244 [t:139821956163328]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:49] openapi_requestor.py:244 [t:139821964572416]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:51] openapi_requestor.py:244 [t:139821947754240]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:54] openapi_requestor.py:244 [t:139821956163328]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:45:58] openapi_requestor.py:244 [t:139821947754240]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:46:04] openapi_requestor.py:244 [t:139821964572416]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:46:05] openapi_requestor.py:244 [t:139821956163328]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:46:16] openapi_requestor.py:244 [t:139821964572416]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:46:26] evaluation_manager.py:472 [t:139823724164928]: start to merge evaluation result dataset\n"
     ]
    }
   ],
   "source": [
    "from qianfan.evaluation import EvaluationManager\n",
    "\n",
    "em = EvaluationManager(local_evaluators=local_evaluators)\n",
    "result = em.eval(\n",
    "    [eb_turbo_service], ds,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:12:22.765504Z",
     "start_time": "2024-02-01T06:12:22.753890Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] [03-19 18:48:27] dataset.py:934 [t:139823724164928]: list local dataset data by None\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '新华社受权于18日全文播发修改后的《中华人民共和国立法法》，修改后的立法法分为“总则”“法律”“行政法规”“地方性法规、自治条例和单行条例、规章”“适用与备案审查”“附则”等6章，共计105条。', 'role': 'user'}], 'expected_output': '修改后的立法法全文公布', 'llm_output': '《中华人民共和国立法法》是为了规范立法活动，健全国家立法制度，提高立法质量，完善中国特色社会主义法律体系，发挥立法的引领和推动作用，保障和发展社会主义民主，全面推进依法治国，建设社会主义法治国家，根据宪法而制定的。\\n\\n此次修改后的《中华人民共和国立法法》全文于2023年1月18日由新华社受权播发。全文分为“总则”、“法律”、“行政法规”、“地方性法规、自治条例和单行条例、规章”、“适用与备案审查”、“附则”等6章，共计105条。\\n\\n这次修改主要集中在完善了立法原则、扩大了全国人大常委会立法权、加强了人大对立法工作的主导作用、健全了法律草案表决程序、完善了授权决定制度、规范了设区的市的立法权等方面。这些修改将有利于发挥立法的引领和推动作用，保障和发展社会主义民主，全面推进依法治国，建设社会主义法治国家。\\n\\n总的来说，这次修改后的《中华人民共和国立法法》将更好地服务于中国特色社会主义法治体系建设，促进全面依法治国工作的开展。', 'Relevance': '评分：7\\n\\n原因：摘要“修改后的立法法全文公布”确实捕捉到了新闻文章的核心内容，即《中华人民共和国立法法》已经修改并全文播发。然而，摘要省略了关于立法法结构的具体细节（如分为6章，共计105条），这些信息虽然可能是次要的，但仍然是对主要事件的有益补充。由于摘要简洁地传达了主要信息，但略去了一些细节，因此给予7分的评分。', 'Coherence': '评分: 7\\n原因: 摘要确实捕捉到了新闻的主要信息，即“修改后的立法法全文公布”。然而，摘要省略了一些重要的细节，比如立法法被分为6章，共计105条。这些细节对于全面了解新闻内容是有帮助的。尽管如此，摘要还是提供了一个简洁明了的概述，符合其基本目标。在连贯性方面，虽然摘要只有一句话，但它独立成句，表达清晰，因此在这方面也没有问题。综合考虑，给出了7分的评分。', 'Consistency': '评分: 8\\n原因: 摘要“修改后的立法法全文公布”确实反映了新闻的主要内容，即修改后的《中华人民共和国立法法》已经被全文播发。然而，摘要省略了一些细节，比如立法法的具体章节和条数。尽管这些细节在某些情况下可能是重要的，但它们对于传达新闻的基本信息来说不是必需的。因此，这个摘要在一致性方面做得相当好，但由于省略了一些细节，所以没有得到满分。', 'Fluency': '评分: 3\\n原因: 摘要“修改后的立法法全文公布”非常简洁且流畅，没有语法、拼写或标点错误。它准确地传达了新闻的主要内容，即修改后的立法法已经全文公布。虽然摘要省略了一些细节，如立法法的章节和条数，但这些信息对于传达新闻的主要内容并不是必需的。因此，这个摘要的流畅度评分是3，表示它易于阅读和遵循。'}, {'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '一辆小轿车，一名女司机，竟造成9死24伤。日前，深圳市交警局对事故进行通报：从目前证据看，事故系司机超速行驶且操作不当导致。目前24名伤员已有6名治愈出院，其余正接受治疗，预计事故赔偿费或超一千万元。', 'role': 'user'}], 'expected_output': '深圳机场9死24伤续：司机全责赔偿或超千万', 'llm_output': '这起事故是非常悲惨的，对受害者和家人造成了巨大的痛苦和损失。对于事故的原因，交警局的通报已经给出了明确的解释，即司机超速行驶且操作不当。这种行为是非常危险和不负责任的，不仅违反了交通规则，也导致了严重的后果。\\n\\n目前，事故的调查和处置工作仍在进行中。对于受伤的人员，医疗团队正在全力救治，已经有6名伤员治愈出院，这表明医疗技术和设备的进步在很大程度上挽救了生命。对于那些仍在接受治疗的人，他们需要继续支持和关心，以确保他们能够尽快康复。\\n\\n至于赔偿问题，预计事故赔偿费或超一千万元，这是一个非常庞大的数字，将对事故责任方造成巨大的经济压力。然而，赔偿并不是目的本身，而是为了尽可能地弥补受害者的损失和抚恤他们的家人。\\n\\n总之，这起事故再次提醒我们，遵守交通规则和保持安全驾驶是非常重要的。司机应该时刻保持警觉，遵守限速，谨慎操作，以确保自己和他人的安全。只有这样，才能避免类似的悲剧再次发生。', 'Relevance': '评分: 7\\n\\n原因: 摘要“深圳机场9死24伤续：司机全责赔偿或超千万”确实捕捉到了新闻的主要信息点，即事故发生地点、伤亡情况和事故责任及预计的赔偿费用。但是，摘要中提到的“深圳机场”与原文中的“深圳市”不完全一致，虽然可能是指同一地区，但这种差异可能导致读者对事故发生的具体地点产生误解。此外，摘要未提及女司机超速行驶和操作不当这一关键原因，这是导致事故的重要因素。因此，虽然摘要包含了部分主要信息，但由于地点描述的不准确性和略去了部分关键细节，所以评分稍低。', 'Coherence': '评分: 7\\n原因: 摘要确实涵盖了新闻的主要信息，包括事故发生地点（深圳）、伤亡情况（9死24伤）、事故原因（司机全责）以及预计的赔偿费用（可能超过一千万元）。然而，摘要在表述上略显简略，例如没有明确指出是“小轿车”事故，也没有提到“超速行驶且操作不当”这一具体的事故原因。此外，摘要的标题中提到了“深圳机场”，但新闻原文中并未提及机场，可能是摘要在编写时出现了误差。尽管有这些不足，但摘要总体上还是传达了新闻的主要内容，因此给予7分的评分。', 'Consistency': '评分: 7\\n\\n原因: 摘要中提到了“深圳机场9死24伤续：司机全责赔偿或超千万”，与新闻原文相比，存在一些问题。首先，新闻中并未提到事故发生在深圳机场，这是一个重要的细节错误。其次，摘要中简化了事故原因，将其归结为“司机全责”，虽然新闻中确实提到了司机超速行驶且操作不当，但“全责”这一表述可能过于绝对，忽略了可能存在的其他因素。最后，关于赔偿金额“或超千万”的部分，摘要与新闻原文是一致的。由于摘要中存在一些事实错误和表述问题，因此给予7分的评分。', 'Fluency': '评分: 2\\n\\n原因: 摘要的流畅度存在一些问题。首先，地点“深圳机场”在原文中并未提及，这是一个错误的信息。其次，“9死24伤续”这样的表述不太清晰，可能会让读者感到困惑，不清楚“续”指的是什么。虽然摘要试图传达事故的责任在司机，并且赔偿可能超过千万元，但由于上述问题，其流畅度和清晰度受到了一定影响。因此，给予流畅度评分2。'}, {'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '1月18日，习近平总书记对政法工作作出重要指示：2014年，政法战线各项工作特别是改革工作取得新成效。新形势下，希望全国政法机关主动适应新形势，为公正司法和提高执法司法公信力提供有力制度保障。', 'role': 'user'}], 'expected_output': '孟建柱：主动适应形势新变化提高政法机关服务大局的能力', 'llm_output': '关于这个问题，您可以参阅相关内容网站，您也可以问我一些其他问题，我会尽力为您解答。', 'Relevance': '评分: 2\\n原因: 摘要中提到了“孟建柱”和“提高政法机关服务大局的能力”，但这与源文档中的内容并不相关。源文档中主要讲述的是习近平总书记对政法工作的指示，强调了政法战线取得的新成效和对全国政法机关的期望。摘要没有涵盖这些主要观点，而且引入了与源文档无关的信息，因此评分较低。', 'Coherence': '评分: 2\\n原因: 摘要中提到了“孟建柱”和“提高政法机关服务大局的能力”，但原文中并没有提到孟建柱，这是一个明显的错误。同时，摘要也没有涵盖原文中关于习近平总书记对政法工作的重要指示，特别是关于适应新形势和提供有力制度保障以提高执法司法公信力的内容。因此，摘要在涵盖主要主题和关键点方面存在明显不足，导致评分较低。', 'Consistency': '评分: 2\\n原因: 摘要中提到的“孟建柱”与新闻中的“习近平总书记”不符，人物错误；同时，摘要中的“提高政法机关服务大局的能力”并未在新闻中出现，属于摘要自行添加的信息。因此，该摘要在一致性方面存在明显问题，评分较低。', 'Fluency': '评分：1\\n原因：此摘要的流畅度较差，主要问题在于它未能准确反映原始新闻的内容。原始新闻是关于习近平总书记对政法工作的指示，而摘要却提到了“孟建柱”，并且摘要的内容与原始新闻并不相关。此外，摘要的表述也存在问题，它并没有清晰地传达出任何有关政法工作的信息。因此，此摘要在流畅度和内容准确性方面都存在问题，评分较低。'}]\n"
     ]
    }
   ],
   "source": [
    "result_dataset = result.result_dataset\n",
    "print(result_dataset.list())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:12:52.219586Z",
     "start_time": "2024-02-01T06:12:52.215252Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] [03-19 18:48:27] dataset.py:934 [t:139823724164928]: list local dataset data by None\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '新华社受权于18日全文播发修改后的《中华人民共和国立法法》，修改后的立法法分为“总则”“法律”“行政法规”“地方性法规、自治条例和单行条例、规章”“适用与备案审查”“附则”等6章，共计105条。', 'role': 'user'}], 'expected_output': '修改后的立法法全文公布', 'llm_output': '《中华人民共和国立法法》是为了规范立法活动，健全国家立法制度，提高立法质量，完善中国特色社会主义法律体系，发挥立法的引领和推动作用，保障和发展社会主义民主，全面推进依法治国，建设社会主义法治国家，根据宪法而制定的。\\n\\n此次修改后的《中华人民共和国立法法》全文于2023年1月18日由新华社受权播发。全文分为“总则”、“法律”、“行政法规”、“地方性法规、自治条例和单行条例、规章”、“适用与备案审查”、“附则”等6章，共计105条。\\n\\n这次修改主要集中在完善了立法原则、扩大了全国人大常委会立法权、加强了人大对立法工作的主导作用、健全了法律草案表决程序、完善了授权决定制度、规范了设区的市的立法权等方面。这些修改将有利于发挥立法的引领和推动作用，保障和发展社会主义民主，全面推进依法治国，建设社会主义法治国家。\\n\\n总的来说，这次修改后的《中华人民共和国立法法》将更好地服务于中国特色社会主义法治体系建设，促进全面依法治国工作的开展。', 'Relevance': '评分：7\\n\\n原因：摘要“修改后的立法法全文公布”确实捕捉到了新闻文章的核心内容，即《中华人民共和国立法法》已经修改并全文播发。然而，摘要省略了关于立法法结构的具体细节（如分为6章，共计105条），这些信息虽然可能是次要的，但仍然是对主要事件的有益补充。由于摘要简洁地传达了主要信息，但略去了一些细节，因此给予7分的评分。', 'Coherence': '评分: 7\\n原因: 摘要确实捕捉到了新闻的主要信息，即“修改后的立法法全文公布”。然而，摘要省略了一些重要的细节，比如立法法被分为6章，共计105条。这些细节对于全面了解新闻内容是有帮助的。尽管如此，摘要还是提供了一个简洁明了的概述，符合其基本目标。在连贯性方面，虽然摘要只有一句话，但它独立成句，表达清晰，因此在这方面也没有问题。综合考虑，给出了7分的评分。', 'Consistency': '评分: 8\\n原因: 摘要“修改后的立法法全文公布”确实反映了新闻的主要内容，即修改后的《中华人民共和国立法法》已经被全文播发。然而，摘要省略了一些细节，比如立法法的具体章节和条数。尽管这些细节在某些情况下可能是重要的，但它们对于传达新闻的基本信息来说不是必需的。因此，这个摘要在一致性方面做得相当好，但由于省略了一些细节，所以没有得到满分。', 'Fluency': '评分: 3\\n原因: 摘要“修改后的立法法全文公布”非常简洁且流畅，没有语法、拼写或标点错误。它准确地传达了新闻的主要内容，即修改后的立法法已经全文公布。虽然摘要省略了一些细节，如立法法的章节和条数，但这些信息对于传达新闻的主要内容并不是必需的。因此，这个摘要的流畅度评分是3，表示它易于阅读和遵循。'}\n",
      "{'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '一辆小轿车，一名女司机，竟造成9死24伤。日前，深圳市交警局对事故进行通报：从目前证据看，事故系司机超速行驶且操作不当导致。目前24名伤员已有6名治愈出院，其余正接受治疗，预计事故赔偿费或超一千万元。', 'role': 'user'}], 'expected_output': '深圳机场9死24伤续：司机全责赔偿或超千万', 'llm_output': '这起事故是非常悲惨的，对受害者和家人造成了巨大的痛苦和损失。对于事故的原因，交警局的通报已经给出了明确的解释，即司机超速行驶且操作不当。这种行为是非常危险和不负责任的，不仅违反了交通规则，也导致了严重的后果。\\n\\n目前，事故的调查和处置工作仍在进行中。对于受伤的人员，医疗团队正在全力救治，已经有6名伤员治愈出院，这表明医疗技术和设备的进步在很大程度上挽救了生命。对于那些仍在接受治疗的人，他们需要继续支持和关心，以确保他们能够尽快康复。\\n\\n至于赔偿问题，预计事故赔偿费或超一千万元，这是一个非常庞大的数字，将对事故责任方造成巨大的经济压力。然而，赔偿并不是目的本身，而是为了尽可能地弥补受害者的损失和抚恤他们的家人。\\n\\n总之，这起事故再次提醒我们，遵守交通规则和保持安全驾驶是非常重要的。司机应该时刻保持警觉，遵守限速，谨慎操作，以确保自己和他人的安全。只有这样，才能避免类似的悲剧再次发生。', 'Relevance': '评分: 7\\n\\n原因: 摘要“深圳机场9死24伤续：司机全责赔偿或超千万”确实捕捉到了新闻的主要信息点，即事故发生地点、伤亡情况和事故责任及预计的赔偿费用。但是，摘要中提到的“深圳机场”与原文中的“深圳市”不完全一致，虽然可能是指同一地区，但这种差异可能导致读者对事故发生的具体地点产生误解。此外，摘要未提及女司机超速行驶和操作不当这一关键原因，这是导致事故的重要因素。因此，虽然摘要包含了部分主要信息，但由于地点描述的不准确性和略去了部分关键细节，所以评分稍低。', 'Coherence': '评分: 7\\n原因: 摘要确实涵盖了新闻的主要信息，包括事故发生地点（深圳）、伤亡情况（9死24伤）、事故原因（司机全责）以及预计的赔偿费用（可能超过一千万元）。然而，摘要在表述上略显简略，例如没有明确指出是“小轿车”事故，也没有提到“超速行驶且操作不当”这一具体的事故原因。此外，摘要的标题中提到了“深圳机场”，但新闻原文中并未提及机场，可能是摘要在编写时出现了误差。尽管有这些不足，但摘要总体上还是传达了新闻的主要内容，因此给予7分的评分。', 'Consistency': '评分: 7\\n\\n原因: 摘要中提到了“深圳机场9死24伤续：司机全责赔偿或超千万”，与新闻原文相比，存在一些问题。首先，新闻中并未提到事故发生在深圳机场，这是一个重要的细节错误。其次，摘要中简化了事故原因，将其归结为“司机全责”，虽然新闻中确实提到了司机超速行驶且操作不当，但“全责”这一表述可能过于绝对，忽略了可能存在的其他因素。最后，关于赔偿金额“或超千万”的部分，摘要与新闻原文是一致的。由于摘要中存在一些事实错误和表述问题，因此给予7分的评分。', 'Fluency': '评分: 2\\n\\n原因: 摘要的流畅度存在一些问题。首先，地点“深圳机场”在原文中并未提及，这是一个错误的信息。其次，“9死24伤续”这样的表述不太清晰，可能会让读者感到困惑，不清楚“续”指的是什么。虽然摘要试图传达事故的责任在司机，并且赔偿可能超过千万元，但由于上述问题，其流畅度和清晰度受到了一定影响。因此，给予流畅度评分2。'}\n",
      "{'llm_tag': 'None_None_ERNIE-Bot-turbo', 'input_chats': [{'content': '1月18日，习近平总书记对政法工作作出重要指示：2014年，政法战线各项工作特别是改革工作取得新成效。新形势下，希望全国政法机关主动适应新形势，为公正司法和提高执法司法公信力提供有力制度保障。', 'role': 'user'}], 'expected_output': '孟建柱：主动适应形势新变化提高政法机关服务大局的能力', 'llm_output': '关于这个问题，您可以参阅相关内容网站，您也可以问我一些其他问题，我会尽力为您解答。', 'Relevance': '评分: 2\\n原因: 摘要中提到了“孟建柱”和“提高政法机关服务大局的能力”，但这与源文档中的内容并不相关。源文档中主要讲述的是习近平总书记对政法工作的指示，强调了政法战线取得的新成效和对全国政法机关的期望。摘要没有涵盖这些主要观点，而且引入了与源文档无关的信息，因此评分较低。', 'Coherence': '评分: 2\\n原因: 摘要中提到了“孟建柱”和“提高政法机关服务大局的能力”，但原文中并没有提到孟建柱，这是一个明显的错误。同时，摘要也没有涵盖原文中关于习近平总书记对政法工作的重要指示，特别是关于适应新形势和提供有力制度保障以提高执法司法公信力的内容。因此，摘要在涵盖主要主题和关键点方面存在明显不足，导致评分较低。', 'Consistency': '评分: 2\\n原因: 摘要中提到的“孟建柱”与新闻中的“习近平总书记”不符，人物错误；同时，摘要中的“提高政法机关服务大局的能力”并未在新闻中出现，属于摘要自行添加的信息。因此，该摘要在一致性方面存在明显问题，评分较低。', 'Fluency': '评分：1\\n原因：此摘要的流畅度较差，主要问题在于它未能准确反映原始新闻的内容。原始新闻是关于习近平总书记对政法工作的指示，而摘要却提到了“孟建柱”，并且摘要的内容与原始新闻并不相关。此外，摘要的表述也存在问题，它并没有清晰地传达出任何有关政法工作的信息。因此，此摘要在流畅度和内容准确性方面都存在问题，评分较低。'}\n"
     ]
    }
   ],
   "source": [
    "result_df = {\"News id\":[],\"Evaluation Type\":[],\"Score\":[]}\n",
    "for i, resp in enumerate(result_dataset.list()):\n",
    "    for metric_name in evaluation_metrics.keys():\n",
    "        result_df[\"News id\"].append(i)\n",
    "        # 添加评估类型及对应得分，因为此处只用了一个大模型，所以只取第一个结果\n",
    "        result_df[\"Evaluation Type\"].append(metric_name)\n",
    "        score = resp[metric_name].split('\\n')[0].replace('：',':').split(':')[-1]\n",
    "        result_df[\"Score\"].append(score)\n",
    "    print(resp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:12:53.971795Z",
     "start_time": "2024-02-01T06:12:53.887181Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Evaluation Type</th>\n",
       "      <th>Coherence</th>\n",
       "      <th>Consistency</th>\n",
       "      <th>Fluency</th>\n",
       "      <th>Relevance</th>\n",
       "      <th>Mean_Score</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>News id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7</td>\n",
       "      <td>8</td>\n",
       "      <td>3</td>\n",
       "      <td>7</td>\n",
       "      <td>6.25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>7</td>\n",
       "      <td>7</td>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "      <td>5.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>1.75</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Evaluation Type  Coherence  Consistency  Fluency  Relevance  Mean_Score\n",
       "News id                                                                \n",
       "0                        7            8        3          7        6.25\n",
       "1                        7            7        2          7        5.75\n",
       "2                        2            2        1          2        1.75"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "pivot_df = pd.DataFrame(result_df, index=None).pivot(\n",
    "    columns=\"Evaluation Type\", index=\"News id\", values=\"Score\"\n",
    ").astype(int)\n",
    "pivot_df['Mean_Score'] = pivot_df.mean(axis=1)\n",
    "display(pivot_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 方法二：封装评估函数\n",
    "\n",
    "除了上述进行本地评估的方法，也可以用ChatCompletion模型构造评估函数，从头开始制作评估的流程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:16:16.100864Z",
     "start_time": "2024-02-01T06:16:16.094037Z"
    }
   },
   "outputs": [],
   "source": [
    "import qianfan\n",
    "\n",
    "def get_geval_score(chat_comp, evaluation_prompt, **kwargs):\n",
    "    prompt, _ = evaluation_prompt.render(**kwargs)\n",
    "    msg = qianfan.Messages()\n",
    "    msg.append(prompt, role='user')\n",
    "    resp = chat_comp.do(\n",
    "        messages=msg,\n",
    "        temperature=0.1,\n",
    "        top_p=1,\n",
    "    )\n",
    "    return resp['result']\n",
    "\n",
    "def split_scores_str(judge_result):\n",
    "    return judge_result.split('\\n')[0].replace('评分: ', '').replace('评分：', '')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后遍历数据集进行评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:26:23.646645Z",
     "start_time": "2024-02-01T06:24:26.705433Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] [03-19 18:48:27] dataset.py:934 [t:139823724164928]: list local dataset data by None\n",
      "[INFO] [03-19 18:48:27] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:48:36] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:48:54] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:49:00] dataset.py:934 [t:139823724164928]: list local dataset data by None\n",
      "[INFO] [03-19 18:49:00] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:49:11] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:49:22] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:49:36] dataset.py:934 [t:139823724164928]: list local dataset data by None\n",
      "[INFO] [03-19 18:49:36] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:49:47] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:50:02] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:50:09] dataset.py:934 [t:139823724164928]: list local dataset data by None\n",
      "[INFO] [03-19 18:50:09] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:50:17] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n",
      "[INFO] [03-19 18:50:25] openapi_requestor.py:244 [t:139823724164928]: requesting llm api endpoint: /chat/completions_pro\n"
     ]
    }
   ],
   "source": [
    "chat_comp = qianfan.ChatCompletion(model=\"ERNIE-Bot-4\")\n",
    "result = {\"Evaluation Type\": [], \"News id\": [], \"Score\": []}\n",
    "for eval_type, (criteria, steps, max_score) in evaluation_metrics.items():\n",
    "    for ind, data in enumerate(ds.list()):\n",
    "        result[\"Evaluation Type\"].append(eval_type)\n",
    "        result[\"News id\"].append(ind)\n",
    "        evaluate = get_geval_score(\n",
    "            chat_comp,\n",
    "            evaluation_prompt,\n",
    "            criteria=criteria,\n",
    "            steps=steps,\n",
    "            prompt=data[0]['prompt'],\n",
    "            response=data[0]['response'][0][0],\n",
    "            max_score=str(max_score),\n",
    "            metric_name=eval_type\n",
    "        )\n",
    "        score = int(split_scores_str(evaluate.strip()))\n",
    "        result[\"Score\"].append(score)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:29:24.522989Z",
     "start_time": "2024-02-01T06:29:24.514981Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Evaluation Type': ['Relevance', 'Relevance', 'Relevance', 'Coherence', 'Coherence', 'Coherence', 'Consistency', 'Consistency', 'Consistency', 'Fluency', 'Fluency', 'Fluency'], 'News id': [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], 'Score': [8, 7, 2, 7, 6, 2, 8, 7, 2, 3, 2, 1]}\n"
     ]
    }
   ],
   "source": [
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "查看最终结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-01T06:29:28.697797Z",
     "start_time": "2024-02-01T06:29:28.686729Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Evaluation Type</th>\n",
       "      <th>Coherence</th>\n",
       "      <th>Consistency</th>\n",
       "      <th>Fluency</th>\n",
       "      <th>Relevance</th>\n",
       "      <th>Mean_Score</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>News id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7</td>\n",
       "      <td>8</td>\n",
       "      <td>3</td>\n",
       "      <td>8</td>\n",
       "      <td>6.50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "      <td>5.50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>1.75</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Evaluation Type  Coherence  Consistency  Fluency  Relevance  Mean_Score\n",
       "News id                                                                \n",
       "0                        7            8        3          8        6.50\n",
       "1                        6            7        2          7        5.50\n",
       "2                        2            2        1          2        1.75"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pivot_df = pd.DataFrame(result, index=None).pivot(\n",
    "    columns=\"Evaluation Type\", index=\"News id\", values=\"Score\"\n",
    ").astype(int)\n",
    "pivot_df['Mean_Score'] = pivot_df.mean(axis=1)\n",
    "display(pivot_df)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
